"""
数据存储模块
负责标定点数据和温度分析结果的持久化存储
支持结构化文本格式的数据保存和加载
"""

import os
import json
import datetime
from typing import List, Dict, Any, Optional


class DataStorage:
    def __init__(self, data_dir: str = "thermal_data"):
        """
        初始化数据存储
        
        Args:
            data_dir: 数据存储目录
        """
        self.data_dir = data_dir
        self.ensure_data_directory()
        
    def ensure_data_directory(self):
        """确保数据目录存在"""
        if not os.path.exists(self.data_dir):
            os.makedirs(self.data_dir)
            
    def save_calibration_data(self, calibration_points: List[Dict], filename: Optional[str] = None) -> str:
        """
        保存标定点数据到固定文件 calibration.txt
        
        Args:
            calibration_points: 标定点列表，每个点包含position, hsv, temperature
            filename: 保留参数兼容性，始终使用 'calibration.txt'
            
        Returns:
            保存的文件路径
        """
        filename = "calibration.txt"  # 始终使用固定文件名
            
        filepath = os.path.join(self.data_dir, filename)
        
        with open(filepath, 'w', encoding='utf-8') as f:
            f.write("# 热成像标定数据\n")
            f.write(f"# 保存时间: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
            f.write(f"# 标定点数量: {len(calibration_points)}\n")
            f.write("# 格式: 序号 | X坐标 | Y坐标 | H值 | S值 | V值 | 温度(°C)\n")
            f.write("-" * 60 + "\n")
            
            for i, point in enumerate(calibration_points, 1):
                # 修复数据结构错误：确保position是坐标，temperature是温度值
                pos = point.get('position')
                hsv = point.get('hsv')  
                temp = point.get('temperature')
                
                # 数据验证和修复
                if not isinstance(pos, (list, tuple)) or len(pos) != 2:
                    # position字段错误，可能和temperature颠倒了
                    if isinstance(temp, (list, tuple)) and len(temp) == 2:
                        pos, temp = temp, pos  # 交换position和temperature
                    else:
                        print(f"警告：标定点{i}的位置数据无效: {pos}, 跳过")
                        continue
                
                if not isinstance(temp, (int, float)):
                    print(f"警告：标定点{i}的温度数据无效: {temp}, 跳过")
                    continue
                    
                if not isinstance(hsv, (list, tuple)) or len(hsv) != 3:
                    # HSV数据无效，使用默认值
                    hsv = [0, 0, 0]
                
                try:
                    f.write(f"{i:2d} | {int(pos[0]):4d} | {int(pos[1]):4d} | "
                           f"{float(hsv[0]):3.0f} | {float(hsv[1]):3.0f} | {float(hsv[2]):3.0f} | {float(temp):6.1f}\n")
                except (ValueError, TypeError) as e:
                    print(f"警告：写入标定点{i}时出错: {e}, 跳过")
                    continue
                       
        return filepath
        
    def load_calibration_data(self, filename: str) -> List[Dict]:
        """
        从文件加载标定点数据
        
        Args:
            filename: 文件名
            
        Returns:
            标定点列表
        """
        filepath = os.path.join(self.data_dir, filename)
        calibration_points = []
        
        if not os.path.exists(filepath):
            return calibration_points
            
        with open(filepath, 'r', encoding='utf-8') as f:
            for line in f:
                line = line.strip()
                if line.startswith('#') or line.startswith('-') or not line:
                    continue
                    
                try:
                    parts = [p.strip() for p in line.split('|')]
                    if len(parts) >= 7:
                        x = int(parts[1])
                        y = int(parts[2])
                        h = float(parts[3])
                        s = float(parts[4])
                        v = float(parts[5])
                        temp = float(parts[6])
                        
                        calibration_points.append({
                            'position': (x, y),
                            'hsv': [h, s, v],
                            'temperature': temp
                        })
                except (ValueError, IndexError):
                    continue
                    
        return calibration_points
        
    def save_calibration_data_with_timestamp(self, calibration_points: List[Dict]) -> str:
        """
        保存标定点数据到带时间戳的备份文件
        
        Args:
            calibration_points: 标定点列表
            
        Returns:
            保存的文件路径
        """
        timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
        filename = f"calibration_backup_{timestamp}.txt"
        return self.save_calibration_data(calibration_points, filename)
        
    def load_default_calibration(self) -> List[Dict]:
        """
        加载默认的标定文件 calibration.txt
        
        Returns:
            标定点列表
        """
        return self.load_calibration_data("calibration.txt")
    
    def clear_calibration_data(self) -> bool:
        """
        清空标定数据文件 calibration.txt
        
        Returns:
            bool: 是否成功清空
        """
        filepath = os.path.join(self.data_dir, "calibration.txt")
        try:
            if os.path.exists(filepath):
                os.remove(filepath)
            return True
        except Exception:
            return False
    
    def has_calibration_data(self) -> bool:
        """
        检查是否存在标定数据文件
        
        Returns:
            bool: 是否存在标定数据
        """
        filepath = os.path.join(self.data_dir, "calibration.txt")
        return os.path.exists(filepath) and os.path.getsize(filepath) > 0
        
    def save_analysis_result(self, analysis_data: Dict[str, Any], filename: Optional[str] = None) -> str:
        """
        保存温度分析结果到文件
        
        Args:
            analysis_data: 分析结果数据，包含regions, image_info等
            filename: 文件名，如果未提供则自动生成时间戳文件名
            
        Returns:
            保存的文件路径
        """
        if filename is None:
            timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
            filename = f"analysis_{timestamp}.txt"
            
        filepath = os.path.join(self.data_dir, filename)
        
        with open(filepath, 'w', encoding='utf-8') as f:
            f.write("# 热成像温度分析结果\n")
            f.write(f"# 分析时间: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
            
            # 写入图像信息
            if 'image_info' in analysis_data:
                info = analysis_data['image_info']
                f.write(f"# 图像尺寸: {info.get('width', 0)}x{info.get('height', 0)}\n")
                f.write(f"# 图像来源: {info.get('source', 'Unknown')}\n")
                
            f.write("# " + "="*50 + "\n\n")
            
            # 写入整体温度统计
            if 'global_stats' in analysis_data:
                stats = analysis_data['global_stats']
                f.write("整体温度统计:\n")
                f.write(f"  最高温度: {stats.get('max_temp', 0):.1f}°C ")
                f.write(f"(位置: {stats.get('max_pos', (0, 0))[0]}, {stats.get('max_pos', (0, 0))[1]})\n")
                f.write(f"  最低温度: {stats.get('min_temp', 0):.1f}°C ")
                f.write(f"(位置: {stats.get('min_pos', (0, 0))[0]}, {stats.get('min_pos', (0, 0))[1]})\n")
                f.write(f"  平均温度: {stats.get('avg_temp', 0):.1f}°C\n\n")
            
            # 写入区域分析结果
            if 'regions' in analysis_data:
                regions = analysis_data['regions']
                f.write(f"区域分析结果 (共{len(regions)}个区域):\n")
                f.write("-" * 80 + "\n")
                
                for i, region in enumerate(regions):
                    f.write(f"区域 {i+1}:\n")
                    f.write(f"  坐标范围: ({region.get('x1', 0)}, {region.get('y1', 0)}) ")
                    f.write(f"到 ({region.get('x2', 0)}, {region.get('y2', 0)})\n")
                    f.write(f"  区域大小: {region.get('width', 0)} x {region.get('height', 0)} 像素\n")
                    
                    stats = region.get('stats', {})
                    f.write(f"  最高温度: {stats.get('max_temp', 0):.1f}°C ")
                    f.write(f"(位置: {stats.get('max_pos', (0, 0))[0]}, {stats.get('max_pos', (0, 0))[1]})\n")
                    f.write(f"  最低温度: {stats.get('min_temp', 0):.1f}°C ")
                    f.write(f"(位置: {stats.get('min_pos', (0, 0))[0]}, {stats.get('min_pos', (0, 0))[1]})\n")
                    f.write(f"  平均温度: {stats.get('avg_temp', 0):.1f}°C\n")
                    f.write(f"  温度差值: {stats.get('temp_diff', 0):.1f}°C\n")
                    f.write(f"  像素数量: {stats.get('pixel_count', 0)}\n")
                    f.write("-" * 40 + "\n")
                    
        return filepath
        
    def load_analysis_result(self, filename: str) -> Dict[str, Any]:
        """
        从文件加载温度分析结果
        
        Args:
            filename: 文件名
            
        Returns:
            分析结果字典
        """
        filepath = os.path.join(self.data_dir, filename)
        result_data = {
            'regions': [],
            'global_stats': {},
            'image_info': {}
        }
        
        if not os.path.exists(filepath):
            return result_data
            
        with open(filepath, 'r', encoding='utf-8') as f:
            content = f.read()
            
        # 这里可以根据需要实现解析逻辑
        # 由于主要用途是保存数据，加载功能可以根据实际需求完善
        return result_data
        
    def list_calibration_files(self) -> List[str]:
        """
        列出所有标定文件
        
        Returns:
            标定文件名列表
        """
        files = []
        for filename in os.listdir(self.data_dir):
            if filename.startswith('calibration_') and filename.endswith('.txt'):
                files.append(filename)
        return sorted(files, reverse=True)  # 按时间倒序
        
    def list_analysis_files(self) -> List[str]:
        """
        列出所有分析结果文件
        
        Returns:
            分析文件名列表
        """
        files = []
        for filename in os.listdir(self.data_dir):
            if filename.startswith('analysis_') and filename.endswith('.txt'):
                files.append(filename)
        return sorted(files, reverse=True)  # 按时间倒序
        
    def export_to_json(self, data: Dict[str, Any], filename: str) -> str:
        """
        将数据导出为JSON格式
        
        Args:
            data: 要导出的数据
            filename: 文件名
            
        Returns:
            保存的文件路径
        """
        filepath = os.path.join(self.data_dir, filename)
        
        # 为JSON导出添加时间戳
        export_data = {
            'export_time': datetime.datetime.now().isoformat(),
            'data': data
        }
        
        with open(filepath, 'w', encoding='utf-8') as f:
            json.dump(export_data, f, ensure_ascii=False, indent=2)
            
        return filepath
        
    def get_data_directory(self) -> str:
        """
        获取数据存储目录路径
        
        Returns:
            数据目录路径
        """
        return os.path.abspath(self.data_dir)